<?php
class ccdSQL
{
    private $link;
    private $bReplication=false;
    private $pMasterLink;

    public $bLogging=false;

    public $bMasterOnly=false;

    private $iQueryCount=0;

    function __construct( )
    {

        $this->config=ccdsConfig::getInstance();

        $mysql_config=$this->config->get( 'mysql' );

        $host=$mysql_config['servers']['slave']['host'];
        $username=$mysql_config['servers']['slave']['user'];
        $password=$mysql_config['servers']['slave']['pass'];
        $database=$mysql_config['servers']['slave']['db'];

        $charset=$mysql_config['charset'];
        $persistent=$mysql_config['persistent'];

        if ( $persistent )
        {
            $this->link=mysql_pconnect( $host, $username, $password, $database ) OR die( mysql_error() );
        }
        else
        {
            $this->link=mysql_connect( $host, $username, $password, $database ) OR die( mysql_error() );
        }

        mysql_select_db( $database, $this->link ) OR die( mysql_error() );

        $res=mysql_query( "SET NAMES '" . mysql_real_escape_string( $charset ) . "'", $this->link );

        if ( !$res )
            die( mysql_error() );

        if ( true == $mysql_config['replication'] )
            $this->addMaster();
    }

    function addMaster( )
    {

        $host=$mysql_config['servers']['master']['host'];
        $username=$mysql_config['servers']['master']['user'];
        $password=$mysql_config['servers']['master']['pass'];
        $database=$mysql_config['servers']['master']['db'];

        $this->pMasterLink=
            mysql_connect( $host, $username, $password, $database )
                || trigger_error( "Could not connect to mysql master db", E_USER_ERROR );
        mysql_select_db( $database, $this->pMasterLink ) OR die( mysql_error() );
        mysql_query( "SET NAMES '" . mysql_real_escape_string( $charset ) . "'", $this->pMasterLink )
            || trigger_error( "Could not set charset on master DB", E_USER_ERROR );

        $this->bReplication=true;
    }

    function is_write( $query )
    {
        if ( $this->bMasterOnly )
            return true;

        if ( preg_match( '/^ *alter .*table *([ _a-zA-Z0-9.]+) /i', $query ) )
            return true;

        if ( preg_match( '/^ *update.* ([ _a-zA-Z0-9.]+) +set/i', $query ) )
            return true;

        if ( preg_match( '/^ *insert *into *([ _a-zA-Z0-9.]+)( |\()/i', $query ) )
            return true;

        if ( preg_match( '/^ *replace *(into)? +([ _.a-zA-Z0-9]+) +( |\(|values|set|select)/i', $query ) )
            return true;

        if ( preg_match( '/^ *delete .*from +([_a-zA-Z0-9.]+) +(where|using)/i', $query ) )
            return true;

        if ( preg_match( '/^ *create.*table +([_a-zA-Z0-9.]+) +(as|select|\()/i', $query ) )
            return true;
        return false;
    }

    function query( $query, $bMaster=false )
    {

        $this->iQueryCount++;

        if ( $this->bLogging )
        {
            $this->log( $query );
        }

        if ( $this->bReplication )
            if ( $this->is_write( $query ) || $bMaster === true )
            {
                $res=mysql_query( $query, $this->pMasterLink );
                return $res;
            }
        $res=mysql_query( $query, $this->link );

        if ( !$res )
        {
            print mysql_error();
            return false;
        }
        return $res;
    }

    function insert_id( )
    {
        if ( true == $this->bReplication )
        {
            return mysql_insert_id( $this->pMasterLink );
        }
        else
        {
            return mysql_insert_id( $this->link );
        }
    }

    function free_result( &$res )
    {
        return mysql_free_result( $res );
    }

    function fetch_assoc( &$res )
    {
        return mysql_fetch_assoc( $res );
    }

    function fetch_array( $res )
    {
        $row=mysql_fetch_array( $res );
        return $row;
    }

    function num_rows( $res )
    {
        return mysql_num_rows( $res );
    }

    function errno( $res )
    {
        return mysql_errno( $res );
    }

    function error( ) {
    // return mysql_error($res);
    }

    function close( )
    {
        mysql_close( $this->link );

        if ( $this->bReplication )
            mysql_close( $this->pMasterLink );
    }

    function getStats( )
    {
        return (int)$this->iQueryCount;
    }

    function affected_rows( )
    {
        if ( $this->bReplication )
        {
            return mysql_affected_rows( $this->pMasterLink );
        }
        else
        {
            return mysql_affected_rows( $this->link );
        }
    }

    function log( $query )
    {
        $query=trim( $query );
        $query=str_replace( "\t", "", $query );

        $fh=fopen( "./query.log", "a" );
        fwrite( $fh, "\n-[" . $this->iQueryCount . "]-------------------------------------------------\n" );
        fwrite( $fh, $query . "\n--------------------------------------------------\n" );
        fclose( $fh );
    }

    function real_escape_string( $string )
    {
        return mysql_real_escape_string( $string, $this->link );
    }

    static function &getInstance( )
    {
        static $obj;

        if ( !$obj )
        {
            $obj=new ccdSQL();
        }
        return $obj;
    }
}
